/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufba.lasid.virtualization;

import br.ufba.lasid.utils.StateXen;
import br.ufba.lasid.virtualization.api.IVirtualMachineHandler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.commons.lang.StringUtils;

/**
 * XenVMHandler is a handler for Xen Virtual Machine instances
 *
 * @author aliriosa
 */
public class XenVMHandler implements IVirtualMachineHandler {

    private String id = null;
    private String name = null;
    private StateXen state;
    public static String XEN_CHK_HOME = "/mnt/drbd1";
    public static String XEN_CFG_HOME = "/etc/xen";

    public XenVMHandler() {
    }

    public XenVMHandler(String name) throws IOException {
        this.name = name;
        this.restoreId();
        this.restoreStateById();
    }

    @Override
    public void restoreId() throws IOException {
        Process p = Runtime.getRuntime().exec("xm domid " + name);
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String pout = in.readLine();
        if (pout != null) {
            this.id = pout;
        }
    }

    @Override
    public void restoreStateById() throws IOException {
        String exe = "xm domstate " + id;
        Process p = Runtime.getRuntime().exec(exe);
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String pout = in.readLine();
        if (pout != null) {
            if (StringUtils.equalsIgnoreCase(pout, StateXen.IDLE.toString())) {
                this.state = StateXen.IDLE;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.CRASHED.toString())) {
                this.state = StateXen.CRASHED;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.DYING.toString())) {
                this.state = StateXen.DYING;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.PAUSED.toString())) {
                this.state = StateXen.PAUSED;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.RUNNING.toString())) {
                this.state = StateXen.RUNNING;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.SHUTDOWN.toString())) {
                this.state = StateXen.SHUTDOWN;
            } else {
                this.state = null;
            }
        } else {
            this.state = null;
        }
    }

    public void restoreStateByName() throws IOException {
        String exe = "xm domstate " + name;
        Process p = Runtime.getRuntime().exec(exe);
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String pout = in.readLine();
        if (pout != null) {
            if (StringUtils.equalsIgnoreCase(pout, StateXen.IDLE.toString())) {
                this.state = StateXen.IDLE;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.CRASHED.toString())) {
                this.state = StateXen.CRASHED;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.DYING.toString())) {
                this.state = StateXen.DYING;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.PAUSED.toString())) {
                this.state = StateXen.PAUSED;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.RUNNING.toString())) {
                this.state = StateXen.RUNNING;
            } else if (StringUtils.equalsIgnoreCase(pout, StateXen.SHUTDOWN.toString())) {
                this.state = StateXen.SHUTDOWN;
            } else {
                this.state = null;
            }
        } else {
            this.state = null;
        }
    }

    protected String getConfigFile() {
        return XEN_CFG_HOME + "/" + id + ".cfg";
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void create() throws Exception {
        System.out.println("[DEBUG]" + "xm create -f " + XEN_CFG_HOME + "/" + id + ".cfg");
        Runtime.getRuntime().exec("xm create -f " + XEN_CFG_HOME + "/" + id + ".cfg");

    }

    @Override
    public void pause() throws Exception {
        System.out.println("[DEBUG]" + "xm pause " + id);
        Runtime.getRuntime().exec("xm pause " + id);
    }

    @Override
    public void checkpoint() throws Exception {
        System.out.println("[DEBUG]" + "xm save -c -f " + id + " " + XEN_CHK_HOME + "/" + id + ".checkpoint");
        Runtime.getRuntime().exec("xm save -c -f " + id + " " + XEN_CHK_HOME + "/" + id + ".checkpoint");
    }

    @Override
    public void restore() throws Exception {
        System.out.println("[DEBUG]" + "xm restore " + XEN_CHK_HOME + "/" + id + ".checkpoint -p");
        Runtime.getRuntime().exec("xm restore " + XEN_CHK_HOME + "/" + id + ".checkpoint -p");
    }

    @Override
    public void connect(String id) throws Exception {
        setId(id);
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("[DEBUG]" + "xm destroy " + id);
        Runtime.getRuntime().exec("xm destroy " + id);
    }

    @Override
    public void unpause() throws Exception {
        System.out.println("[DEBUG]" + "xm unpause " + id);
        Runtime.getRuntime().exec("xm unpause " + id);
    }

    @Override
    public void restoreAndRun() throws Exception {
        System.out.println("[DEBUG]" + "xm restore " + id + ".checkpoint");
        Runtime.getRuntime().exec("xm restore " + id + ".checkpoint");
    }

    public StateXen getStateByName() throws IOException {
        this.restoreStateByName();
        return state;
    }

    public StateXen getState() throws IOException {
        this.restoreStateById();
        return state;
    }

    public void setState(StateXen state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return id;
    }
}
